package lifeOfAFish.scenegraph;

class sgMatrix3D {

	protected float[][] m = new float[4][4];			// the matrix values
	
	// default constructor, sets identitiy matrix
	public sgMatrix3D() {
		m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0f;
	}
	
	public sgMatrix3D(float[] r1, float[] r2, float[] r3){
		// set matrix row by row
		this.arrayCopy(m[0], r1);
		this.arrayCopy(m[1], r2);
		this.arrayCopy(m[2], r3);
		
		float f[] = {0,0,0,1};
		arrayCopy(m[3],f);
	}
	
	// create matrix from 3 homogeneous 3d vectors
	public sgMatrix3D(sgVec3 r1, sgVec3 r2, sgVec3 r3){
		// set matrix row by row
		this.arrayCopy(m[0], r1.v);
		this.arrayCopy(m[1], r2.v);
		this.arrayCopy(m[2], r3.v);
		
		float f[] = {0,0,0,1};
		arrayCopy(m[3],f);
	}
	
	// init array, with entry values as given in array
	public sgMatrix3D(float[] a){
		
		// make sure array is of right size
		if(a.length != 16)
			return;
		
		for (int i = 0; i < 4; i++)
			for (int j = 0; j < 4; j++)
				m[i][j] = a[i*4 + j];
		
	}
	
	public float[] get1D()
	{
		float[] mat = new float[16];
		for (int i = 0; i < 4; i++)
			for (int j = 0; j < 4; j++)
				mat[i*4+j] = this.m[i][j];
		
		return mat;
	}
	
	public float[][] get2D()
	{
		float[][] mat = new float[4][4];
		for (int i = 0; i < 4; i++)
			for (int j = 0; j < 4; j++)
				mat[i][j] = this.m[i][j];
		
		return mat;
	}

	
	// multiply with another matrix
	public static sgMatrix3D multiply(sgMatrix3D X, sgMatrix3D Y){
		
		sgMatrix3D result = new sgMatrix3D();
		result.setZero();
		
		for (int i=0;i<4;i++) {
			for(int j=0;j<4;j++) {
  				for (int k=0;k<4;k++)         
    				result.m[i][j]+=X.m[i][k]*Y.m[k][j];
			}
		} // end for
		
		return result;
  	}
  
	
  	// zero the entire matrix
	public void setZero(){
		for(int i = 0; i < 4; i++)
			for(int j = 0; j < 4; j++)
				this.m[i][j] = 0.0f;
	}
	
	// zero the entire matrix
	public sgMatrix3D identity(){
		this.setZero();
		m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0f;
		return this;
	}
	
	// copy another Matrix
	public void copy(sgMatrix3D T){
		for(int i = 0; i < 4; i++)
			arrayCopy(this.m[i], T.m[i]);	
	}
	
	// Private functions //////////////////////////////
	
	// copies two equally long arrays of floats
	private void arrayCopy(float[] a, float[] b){
	
		if (a.length != b.length) return;
		
		for (int i=0; i<a.length; i++)
			a[i] = b[i];
	}
		
		
	
	
}
